<?php

declare(strict_types=1);

namespace App\Controller\Backend;

use App\Entity\Gallery;
use App\Enum\LogTypeEnum;
use App\Service\UploadFileService;
use App\Utils\Helper\LogHelper;
use App\Utils\Traits\ControllerTrait;
use App\Utils\Traits\JsonTrait;
use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Request;

final class GalleryAdminController extends CRUDController {
    use JsonTrait, ControllerTrait;

    /**
     * 列表
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response|null
     */
    public function preList (Request $request) {
        $gallery = $this->getDoctrine()->getRepository(Gallery::class)->findBy([], ['sort' => 'ASC']);
        return $this->renderWithExtraParams('backend/gallery/list.html.twig', [
            'action'  => 'list',
            'gallery' => $gallery,
        ], null);
    }

    /**
     * 图片上传
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function imageUploadAction (Request $request) {
        if ($this->isAppModeDemo()) {
            return $this->renderJson(['error' => 'Demo模式下禁止图片上传']);
        }

        // 请求方式校验
        if (!($request->isXmlHttpRequest() && $request->getMethod() == 'POST')) {
            return $this->renderJson(['error' => '非法请求']);
        }

        // 关联图片数校验
        $gallery_count_limit = 20;
        $gallery_count = count($this->getDoctrine()->getRepository(Gallery::class)->findAll());
        if ($gallery_count >= $gallery_count_limit) {
            return $this->renderJson(['error' => '最多允许上传（'.$gallery_count_limit.'）张图片']);
        }

        // 图片上传
        $absolute_save_path = $this->container->getParameter('kernel.gallery.absolute.dir');
        $relative_save_path = $this->container->getParameter('kernel.gallery.relative.dir');
        $allow_type = ['jpg', 'png', 'jpeg'];
        $max_size = 1 * 1024 * 1024;
        $file = $_FILES['file_data'];
        $uploadFileService = $this->container->get('app.service.upload_file');
        $upload_result_obj = $uploadFileService->upload($absolute_save_path, $relative_save_path, $allow_type, $max_size, $file);
        if ($upload_result_obj->type == UploadFileService::MESSAGE_TYPE_SUCCESS) {
            // 添加记录
            $gallery = new Gallery();
            $gallery->setName($upload_result_obj->new_file_name);
            $gallery->setOriginalName($upload_result_obj->origin_file_name);
            $gallery->setPath($upload_result_obj->relative_file_path);
            $gallery->setSize($upload_result_obj->file_size);
            $gallery->setAdminUserId($this->getUser()->getId());
            $gallery->setCreatedAt(new \DateTime());
            $this->getDoctrine()->getManager()->persist($gallery);
            $this->getDoctrine()->getManager()->flush();
            // 记录排序值
            $gallery->setSort($gallery->getId());
            $this->getDoctrine()->getManager()->persist($gallery);
            $this->getDoctrine()->getManager()->flush();
            // 记录日志
            $description = '名称:['.$gallery->getOriginalName().'] 大小:['.$gallery->getSize().']';
            LogHelper::buildLog(LogTypeEnum::TYPE_GALLERY_CREATE, $description);

            // 返回数据
            $result = [
                'initialPreview'       => $upload_result_obj->relative_file_path,
                'initialPreviewConfig' => [
                    [
                        'type'     => 'image',
                        'caption'  => $upload_result_obj->origin_file_name,
                        'key'      => $gallery->getId(),
                        'size'     => $upload_result_obj->file_size,
                        'width'    => '120px',
                        'url'      => $this->generateUrl('admin_gallery_image_delete', ['id' => $gallery->getId()]),
                        'filename' => $gallery->getPath(),
                    ],
                ],
                'append'               => true,
            ];
            return $this->jsonSuccess($result);
        } else {
            return $this->renderJson(['error' => $upload_result_obj->message]);
        }
    }

    /**
     * 图片删除
     * @param Request $request
     * @param $id
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     */
    public function imageDeleteAction (Request $request, $id) {
        if ($this->isAppModeDemo()) {
            return $this->renderJson(['error' => 'Demo模式下禁止图片删除']);
        }

        // 请求方式校验
        if (!($request->isXmlHttpRequest() && $request->getMethod() == 'POST')) {
            return $this->renderJson(['error' => '非法请求']);
        }

        // 校验图片资源
        $object = $this->admin->getSubject();
        if (!$object) {
            return $this->renderJson(['error' => '请求的资源不存在']);
        }

        // 记录日志
        $description = '名称:['.$object->getOriginalName().'] 大小:['.$object->getSize().']';
        LogHelper::buildLog(LogTypeEnum::TYPE_GALLERY_DELETE, $description);

        // 删除记录
        $path = $object->getPath();
        $this->getDoctrine()->getManager()->remove($object);
        $this->getDoctrine()->getManager()->flush();
        // 删除对应图片文件
        $file_path = $this->container->getParameter('kernel.public_dir').$path;
        if (is_file($file_path) && file_exists($file_path)) {
            @unlink($file_path);
        }

        return $this->jsonSuccess('操作成功');
    }

    /**
     * 图片排序
     * @param Request $request
     * @param $id
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     */
    public function imageSortAction (Request $request) {
        if ($this->isAppModeDemo()) {
            return $this->renderJson(['error' => 'Demo模式下禁止图片排序']);
        }

        // 请求方式校验
        if (!($request->isXmlHttpRequest() && $request->getMethod() == 'POST')) {
            return $this->renderJson(['error' => '非法请求']);
        }

        $sort = $request->get('sort', []);
        foreach ($sort as $key => $value) {
            $gallery = $this->getDoctrine()->getRepository(Gallery::class)->find($value);
            if (is_object($gallery)) {
                $gallery->setSort($key);
                $this->getDoctrine()->getManager()->persist($gallery);
            }
        }
        $this->getDoctrine()->getManager()->flush();

        return $this->jsonSuccess('操作成功');
    }
}
